#pragma once
#include "..\..\CommLib\CommStructs.h"
#include "..\..\CommLib\PacketConven.h"
#include "..\Render\Render.h"
#include "..\..\Global\globaldef.h"
#include "Material.h"

struct StreamedMesh
{
	enum TEXTURE_CHANNEL
	{
		liveview_color			= 0,
		liveview_normal			= 1,
		liveview_specular		= 2,
		TEXTURE_COUNT	= 3
	};

	enum INSTANCE_CHANNEL
	{
		POSITION		= 0,
		ROTATION		= 1,
		SCALE			= 2,
		INSTANCE_COUNT	= 3
	};

	struct tInstancingProcedural{
		StreamedMesh* m_pInstanceChild;
		Render::tResource* m_pInstanceBuffer;
		
		HeaderStructs::tSurfaceTextureHeader proceduralHeader;
		byte* pProceduralData;
	};

	HMATERIAL m_hDecalMaterial;
	HMATERIAL m_hNormalMaterial;

  	uint m_TriangleCount;
	byte* m_pTriangleData;
	
	bool m_Deformation;
	float m_DeformationScale;
	Render::tResource* m_pVertexBuffer;
	Render::tResource* m_pSOBuffers[2];
	Render::tResource* m_pIndexBuffer;
	D3DXMATRIX m_World;
	tCharBuffer m_ID;
	Render::tShader* m_Shader;
	std::vector<tInstancingProcedural> m_IPPairs;

	StreamedMesh();
	StreamedMesh(const std::string& ID);

	void SetTransform(tMatrix4 *pTransform);
	void SetShader(const std::string& shaderFilename, const int shaderFeatureSet, const int vertexFormat = -1);

	bool GetChildInstance(u_int index, StreamedMesh** pInstanceChildOut, tProceduralData* pProceduralOut);
	bool AddChildInstancing(StreamedMesh* pInstanceChild, HeaderStructs::tSurfaceTextureHeader* data, byte* pSurfaceTextureData);
	bool RemoveChildInstancing(StreamedMesh* pInstanceChild);
	u_int ChildInstancingCount();
	
	void UpdateGeometry(HeaderStructs::tGeometryHeader* data, byte* pTriangleData);
	void UpdateMaterial(HeaderStructs::tSurfaceTextureHeader* pHeader, byte* pMaterial);

	void DrawInstancedChildren();
	void Draw(Render::tShader* pShader = NULL, bool deformationOverride = true, Render::tResource* pInstanceBuffer = NULL, UINT instanceCount = 0);

	//void SetShaderParameters();

	void Release();

	void WriteToDisk();
};